package com.zeus.web.filter;

import com.hengxinyongli.zeus.common.constant.TrackConstant;
import com.hengxinyongli.zeus.common.utils.NetworkInterfaceManager;
import com.zeus.web.utils.SnowflakeIdWorker;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.*;
import java.io.IOException;

/**
 * 链路跟踪的filter
 * 如果没有trackid，生成相关的跟踪id,将配置的调用方,调用方ip进行设置,
 */
public class ApplicationTrackFilter implements Filter {

    @Value("${callFrom:#{null}}}")
    private String callFrom;

    private Logger logger = LoggerFactory.getLogger(ApplicationTrackFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String ipAddress = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();//ip地址
        long trackId = 0;
        String trackKey = MDC.get(TrackConstant.TRACK_ID_KEY);
        if (StringUtils.isEmpty(trackKey)) {
            SnowflakeIdWorker instanceSnowflake = SnowflakeIdWorker.getInstanceSnowflake();
            try {
                trackId = instanceSnowflake.nextId();
                MDC.put(TrackConstant.TRACK_ID_KEY, String.valueOf(trackId));
            } catch (Exception e) {
                logger.error("gen trackId error {}", e);
            }
        }
        long beginTime = System.currentTimeMillis();
        MDC.put(TrackConstant.CALL_IP_KEY, ipAddress);
        MDC.put(TrackConstant.TRACK_BEGINTIME_KEY, String.valueOf(beginTime));//调用开始时间
        MDC.put(TrackConstant.CALL_FROM_KEY, callFrom);//调用发起方
        if (logger.isDebugEnabled()) {
            logger.debug("trackId {},call ip address {},call from key {},call begin time", trackId, ipAddress, callFrom, beginTime);
        }
        chain.doFilter(request, response);
        logger.debug("call time sum {} ms", (System.currentTimeMillis() - beginTime));//总耗时
        MDC.clear();//清空mdc 数据
    }

    @Override
    public void destroy() {

    }
}
